/**********************************************************************
 *@Project： cloudDemo
 *@File: PortalController
 *@Date: 2017/4/13
 *@Copyright (C) 2013-2017 http://www.posun.cn. All Rights Reserved.
 ***********************************************************************
 *注意： 本内容仅限于深圳市普盛实业有限公司内部使用，禁止外泄
 **********************************************************************
 */
package com.posun.edu.system.controller;

import com.posun.edu.system.entity.User;
import com.posun.framework.orm.toolkit.IdWorker;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>
 * TODO<br>
 *
 * @author YL
 * @version 1.0
 * @createTime 2017/4/13 17:46
 * @ChangeLog
 */
@RestController
@RequestMapping("/")
public class PortalController {

    @RequestMapping("/")
    public ModelAndView index(Model model, HttpServletRequest request) {
        System.out.println(request.getSession().getId());
        request.getSession().setAttribute("randomId", IdWorker.getId());
        model.addAttribute("name", "posuncloud");
        ModelAndView modelAndView = new ModelAndView("index");
        return modelAndView;
    }

    @RequestMapping(value = "/sso/login", method = RequestMethod.GET)
    public ModelAndView login(Model model, HttpServletRequest request) {
        if (SecurityUtils.getSubject().isAuthenticated()) {
            return new ModelAndView("index");
        }

        System.out.println(request.getSession().getId());
        model.addAttribute("uid", request.getSession().getId());
        request.getSession().setAttribute("randomId", IdWorker.getId());

        ModelAndView modelAndView = new ModelAndView("login");
        return modelAndView;
    }

    @RequestMapping(value = "/sso/login", method = RequestMethod.POST)
    public ModelAndView login(User user, RedirectAttributes redirectAttributes, HttpServletRequest request) {
        String username = user.getUserName();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());
        // 获取当前的Subject
        Subject currentUser = SecurityUtils.getSubject();
        try {
            // 在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
            // 每个Realm都能在必要时对提交的AuthenticationTokens作出反应
            // 所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
            currentUser.login(token);
        } catch (UnknownAccountException uae) {
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
            redirectAttributes.addFlashAttribute("message", "未知账户");
        } catch (IncorrectCredentialsException ice) {
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
            redirectAttributes.addFlashAttribute("message", "密码不正确");
        } catch (LockedAccountException lae) {
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
            redirectAttributes.addFlashAttribute("message", "账户已锁定");
        } catch (ExcessiveAttemptsException eae) {
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
            redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数过多");
        } catch (AuthenticationException ae) {
            // 通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
            ae.printStackTrace();
            redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
        }
        // 验证是否登录成功
        if (currentUser.isAuthenticated()) {
            System.out.println("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
            request.getSession().setAttribute(username, request.getRequestedSessionId());
            System.out.println("当前用户的sessionID：" + request.getSession().getId());
            return new ModelAndView("redirect:/dict");
        } else {
            token.clear();
            return new ModelAndView("redirect:/sso/login");
        }
    }
}
